
#include <BRender>
#include <BPainter>
#include <BGeometry>
#include <ctime>

#include "PixmapHandler.h"

PixmapHandler::PixmapHandler(BGeometry* screen)
{
	_screen = screen;
	_pixmap = dynamic_cast<BPixmap*>(_screen->texture());
	if (_pixmap)
	{
		_widget = _pixmap->widget(0);
		_pressed = false;
		connect(_pixmap, Signal_Fresh, &PixmapHandler::slotDisplayRefresh);
		connect(_widget, Signal_Hide, &PixmapHandler::slotWidgetHiden);
	}
}

void PixmapHandler::slotDisplayRefresh()
{
	this->fresh();
}
void PixmapHandler::slotWidgetHiden()
{
	if(this->viewer()->contain(_widget))
	{
		this->viewer()->removeChild(_widget);
		_widget->show();
	}
}

bool PixmapHandler::event(const BEvent& event)
{
	if (_pixmap && event.type() <= Event_KeyDown)
		return _pixmap->event(event);
	return BHandler::event(event);
}

void PixmapHandler::paint(BPainter& painter)
{
	if(BCamera* camera = this->camera())
	{
		BVector pos = camera->position();

		BString text("mouse point : ");
		text << _debugPoint.x() << ", " << _debugPoint.y();
		text << "\ncamera position : ";
		text << pos.x() << ", " << pos.y() << ", " << pos.z();

		painter.setColor(Color_Text);
		painter.drawText(20, 56, painter.widget()->width(), 100, text);
	}
}
void PixmapHandler::render(BRender& render)
{
	render.setLighting(false);

	//render.setColor(255, 0, 0, 255);
	//render.setPointSize(5);
	//render.setPointSmooth(true);
	//render.drawPoint(_debugVector);

	//render.setColor(0, 255, 0, 255);
	//render.drawLine(_debugLine);

	BQuad quad;
	quad.a().set(-100, -100, 0);
	quad.b().set(-100, -100, 40);
	quad.c().set(-50, -100, 40);
	quad.d().set(-50, -100, 0);
	render.bind(_widget);
	render.fillQuad(quad);
	render.unbind();

}

void PixmapHandler::updateEvent(const BEvent& event)
{
	if (_pixmap)
	{
		_pixmap->event(event);
	}
}

bool PixmapHandler::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool PixmapHandler::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool PixmapHandler::mousePressEvent(const BMouseEvent& mouseEvent)
{
	if (_pixmap)
	{
		if (_inside)
			_pressed = true;
		_mouseEvent = mouseEvent;
		_mouseEvent.setGlobalPos(_debugPoint);
		_mouseEvent.setAbsolutePos(_debugPoint);
		_pixmap->event(_mouseEvent);
		this->viewer()->fresh();
	}
	return false;
}
bool PixmapHandler::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	if (_pixmap)
	{
		_pressed = false;
		_mouseEvent = mouseEvent;
		_mouseEvent.setGlobalPos(_debugPoint);
		_mouseEvent.setAbsolutePos(_debugPoint);
		_pixmap->event(_mouseEvent);
		this->viewer()->fresh();
	}
	return false;
}
bool PixmapHandler::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	if (_pixmap && _screen)
	{
		const BPoint& pos = mouseEvent.pos();

		if (!_pressed)
			_inside = false;

		BLine line = this->viewer()->line(pos);
		_debugLine = line;
		BPicker picker(line);
		if (const BPickItem* item = picker.apply(_screen))
		{
			BMatrix matrix = _screen->matrix();
			_debugVector = item->absolutePoint();
			_inside = true;
			BVectorArray* vertices = _screen->vertices();
			BVector v0 = (*vertices)[0] * matrix;
			BVector v1 = (*vertices)[1] * matrix;
			BVector v2 = (*vertices)[2] * matrix;
			BVector v3 = (*vertices)[3] * matrix;

			BLine topLine(v3, v2);
			BLine leftLine(v3, v0);
			BVector point = item->absolutePoint();
			BReal quadX = leftLine.distance(point);
			BReal quadY = topLine.distance(point);
			BReal quadWidth = (v0 - v1).length();
			BReal quadHeight = (v0 - v3).length();
			_debugPoint.x() = (int)(quadX / quadWidth * _pixmap->width());
			_debugPoint.y() = (int)(quadY / quadHeight * _pixmap->height());

			_mouseEvent.setType(Event_MouseMove);
			_mouseEvent.setGlobalPos(_debugPoint);
			_mouseEvent.setAbsolutePos(_debugPoint);
			_pixmap->event(_mouseEvent);
		}
		this->viewer()->fresh();
	}
	return false;
}

bool PixmapHandler::mouseWheelEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool PixmapHandler::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	if (_pixmap)
	{
		_mouseEvent = mouseEvent;
		_mouseEvent.setGlobalPos(_debugPoint);
		_mouseEvent.setAbsolutePos(_debugPoint);
		_pixmap->event(_mouseEvent);
	}
	return false;
}
bool PixmapHandler::mouseDoubleClickEvent(const BMouseEvent& mouseEvent)
{
	if (_inside && _pixmap)
	{
		this->viewer()->addChild(_widget);
	}
	return false;
}

bool PixmapHandler::dragEnterEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool PixmapHandler::dragLeaveEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool PixmapHandler::dragMoveEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool PixmapHandler::dragDropEvent(const BDragEvent& dragEvent)
{
	return false;
}

